#include <stdio.h>
#include <stdlib.h>

// 链栈类型定义
typedef struct stack
{
    char data;
    struct stack *next;
} Stack, *LinkStack;

// 判空栈
int stackEmpty(LinkStack L)
{
    return L == NULL;
}
// 进栈, 这里修改的链栈本身,所以形参使用二级指针,实参传入链栈本身的地址
void push(LinkStack *L, char data)
{
    Stack *p = (LinkStack)malloc(sizeof(Stack));
    p->data = data;
    p->next = (*L);
    // 新元素放至栈顶
    (*L) = p;
    // printf("v=%c, p=%p, L=%p\n", data, p, (*L));
}
// 退栈(出栈)
void pop(LinkStack *L, char *data)
{
    if (stackEmpty((*L)))
    {
        printf(">>stack is empty!\n");
        return;
    }

    Stack *p = (*L);
    // 传地址才会修改原始值
    (*data) = p->data;
    (*L) = p->next;
    free(p);
}

char pop2(LinkStack *L)
{
    if (stackEmpty((*L)))
    {
        printf(">>stack is empty!\n");
        exit(0);
    }

    // Stack *p = (*L); // 直接修改链表，不通过复制(最后还需释放结点)链表修改
    // 出栈元素
    char data = (*L)->data;
    // printf("v=%c, cur=%p, next=%p\n", data, (*L),(*L)->next);
    // 将
    (*L) = (*L)->next;

    printf("v=%c, cur=%p\n", data, (*L));
    
    // 若链栈初始化不为空，则需要判断下一个结点是否为 NULL 
    // if(stackEmpty((*L)->next)){
    //     exit(0);
    // }
    return data;
}

// 获取栈顶元素
char getTop(LinkStack L)
{
    if (stackEmpty(L))
    {
        printf(">>stack is empty!\n");
        exit(0);
    }
    return L->data;
}

int main()
{
    LinkStack stack = NULL; // = (LinkStack)malloc(sizeof(Stack)); 
    printf("-----------linkstack push----------p=%p\n", stack);
    char ch;
    while ((ch = getchar()) != '\n')
    {
        push(&stack, ch);
    }

    printf("-----------linkstack pop----------\n");
    while (!stackEmpty(stack))
    {
        printf("pop value=%c\n", pop2(&stack));
    }

    return 0;
}